﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tetris
{
    enum FigurePosition
    {
        North,
        East,
        South,
        West
    }

    enum CurrentFigure
    {
        Cube,
        Piptik,
        Horse,
        Twos,
        Stick
    }

    class GameLogic
    {
        public GameField field;
        public Frame frame;
        public Drawer drw;
        List<Figures> figureList;
        List<Figures> finishedList;
        List<Figures> toPrintList;
        ConsoleKeyInfo key = default(ConsoleKeyInfo);
        //ConsoleKeyInfo currentKey = default(ConsoleKeyInfo);
        private readonly Handler hd;
        Random rnd;
        FigurePosition currentPosition;
        FigurePosition nextPosition;
        CurrentFigure currentFigure;
        List<int> coordYCompleteLine;
        //bool isGameOver = false;
        //bool isPaused = true;
        //bool isNewRound = false;

        public GameLogic(GameField field, Handler keyH)
        {
            this.field = field;
            frame = new Frame(this.field);
            drw = new Drawer();
            drw.FrameDrawer(this.field, frame);
            figureList = new List<Figures>();
            finishedList = new List<Figures>();
            toPrintList = new List<Figures>();
            List<int> coordYCompleteLine = new List<int>();
            rnd = new Random();
            currentPosition = FigurePosition.North;
            hd = keyH;
            hd.KeyLeft += MoveFigureLeft;
            hd.KeyRight += MoveFigureRight;
            hd.KeyDown += MoveFigureDown;
            hd.KeyUp += RotateFigure;
        }

        public void CheckNextPosition(FigurePosition curPosit)
        {
            if (currentPosition == FigurePosition.North)
            {
                nextPosition = FigurePosition.East;
            }
            else if (currentPosition == FigurePosition.East)
            {
                nextPosition = FigurePosition.South;
            }
            else if (currentPosition == FigurePosition.South)
            {
                nextPosition = FigurePosition.West;
            }
            else if (currentPosition == FigurePosition.West)
            {
                nextPosition = FigurePosition.North;
            }
        }

        public void NextFigureGeneration()
        {

            int a = rnd.Next(1, 6);
            switch (a)
            {
                case 1:
                    {
                        figureList.Add(new Cube(field.StartX + (field.Width / 2), field.StartY + 1));
                        figureList.Add(new Cube(figureList[0].Xfigure, figureList[0].Yfigure - 1));
                        figureList.Add(new Cube(figureList[0].Xfigure + 1, figureList[0].Yfigure - 1));
                        figureList.Add(new Cube(figureList[0].Xfigure + 1, figureList[0].Yfigure));
                        currentFigure = CurrentFigure.Cube;
                        break;
                    }
                case 2:
                    {
                        figureList.Add(new Piptik(field.StartX + (field.Width / 2), field.StartY + 1));
                        figureList.Add(new Piptik(figureList[0].Xfigure - 1, figureList[0].Yfigure + 1));
                        figureList.Add(new Piptik(figureList[0].Xfigure, figureList[0].Yfigure + 1));
                        figureList.Add(new Piptik(figureList[0].Xfigure + 1, figureList[0].Yfigure + 1));
                        currentFigure = CurrentFigure.Piptik;

                        break;
                    }
                case 3:
                    {
                        figureList.Add(new Horse(field.StartX + (field.Width / 2), field.StartY + 1));
                        figureList.Add(new Horse(figureList[0].Xfigure, figureList[0].Yfigure + 1));
                        figureList.Add(new Horse(figureList[0].Xfigure + 1, figureList[0].Yfigure + 1));
                        figureList.Add(new Horse(figureList[0].Xfigure + 2, figureList[0].Yfigure + 1));
                        currentFigure = CurrentFigure.Horse;
                        break;
                    }
                case 4:
                    {
                        figureList.Add(new Twos(field.StartX + (field.Width / 2), field.StartY + 1));
                        figureList.Add(new Twos(figureList[0].Xfigure + 1, figureList[0].Yfigure));
                        figureList.Add(new Twos(figureList[0].Xfigure + 1, figureList[0].Yfigure + 1));
                        figureList.Add(new Twos(figureList[0].Xfigure + 2, figureList[0].Yfigure + 1));
                        currentFigure = CurrentFigure.Twos; 
                        break;
                    }
                case 5:
                    {
                        figureList.Add(new Stick(field.StartX + (field.Width / 2), field.StartY + 1));
                        figureList.Add(new Stick(figureList[0].Xfigure + 1, figureList[0].Yfigure));
                        figureList.Add(new Stick(figureList[0].Xfigure + 2, figureList[0].Yfigure));
                        figureList.Add(new Stick(figureList[0].Xfigure + 3, figureList[0].Yfigure));
                        currentFigure = CurrentFigure.Stick;
                        break;
                    }
                default:
                    break;
            }

        }

        private void MoveFigureLeft(object sender, EventArgs e)
        {
            if (!Validation.IsOnLeft(field, figureList) && !Validation.IsOnFinishedListLeftSideMoving(figureList, finishedList))
            {
                foreach (var item in figureList)
                {
                    item.MoveLeft();
                }
            }
        }

        private void MoveFigureRight(object sender, EventArgs e)
        {
            if (!Validation.IsOnRight(field, figureList) && !Validation.IsOnFinishedListRightSideMoving(figureList, finishedList))
            {
                foreach (var item in figureList)
                {
                    item.MoveRight();
                }
            }
        }

        private void MoveFigureDown(object sender, EventArgs e)
        {
            if (!Validation.IsOnDown(field, figureList))
            {
                foreach (var item in figureList)
                {
                    item.MoveDown();
                }
            }
        }

        private void RotateFigure(object sender, EventArgs e)
        {
            if (currentFigure == CurrentFigure.Piptik)
            {
                CheckNextPosition(currentPosition);
                if (nextPosition == FigurePosition.East)
                {
                    figureList[0].Xfigure += 1; figureList[0].Yfigure += 1;
                    figureList[1].Xfigure += 1; figureList[1].Yfigure -= 1;
                    figureList[3].Xfigure -= 1; figureList[3].Yfigure += 1;
                    currentPosition = FigurePosition.East;
                }
                if (nextPosition == FigurePosition.South)
                {
                    figureList[0].Xfigure -= 1; figureList[0].Yfigure += 1;
                    figureList[1].Xfigure += 1; figureList[1].Yfigure += 1;
                    figureList[3].Xfigure -= 1; figureList[3].Yfigure -= 1;
                    currentPosition = FigurePosition.South;
                }
                if (nextPosition == FigurePosition.West)
                {
                    figureList[0].Xfigure -= 1; figureList[0].Yfigure -= 1;
                    figureList[1].Xfigure -= 1; figureList[1].Yfigure += 1;
                    figureList[3].Xfigure += 1; figureList[3].Yfigure -= 1;
                    currentPosition = FigurePosition.West;
                }
                if (nextPosition == FigurePosition.North)
                {
                    figureList[0].Xfigure += 1; figureList[0].Yfigure -= 1;
                    figureList[1].Xfigure -= 1; figureList[1].Yfigure -= 1;
                    figureList[3].Xfigure += 1; figureList[3].Yfigure += 1;
                    currentPosition = FigurePosition.North;
                }
            }

            if (currentFigure == CurrentFigure.Twos)
            {
                CheckNextPosition(currentPosition);
                if (nextPosition == FigurePosition.East)
                {
                    figureList[0].Xfigure += 2;
                    figureList[1].Xfigure += 1; figureList[1].Yfigure += 1;
                    figureList[3].Xfigure -= 1; figureList[3].Yfigure += 1;
                    currentPosition = FigurePosition.West;
                }
                if (nextPosition == FigurePosition.North)
                {
                    figureList[0].Xfigure -= 2;
                    figureList[1].Xfigure -= 1; figureList[1].Yfigure -= 1;
                    figureList[3].Xfigure += 1; figureList[3].Yfigure -= 1;
                    currentPosition = FigurePosition.North;
                }
            }

            if (currentFigure == CurrentFigure.Horse)
            {
                CheckNextPosition(currentPosition);
                if (nextPosition == FigurePosition.East)
                {
                    figureList[0].Xfigure += 2;
                    figureList[1].Xfigure += 1; figureList[1].Yfigure -= 1;
                    figureList[3].Xfigure -= 1; figureList[3].Yfigure += 1;
                    currentPosition = FigurePosition.East;
                }
                if (nextPosition == FigurePosition.South)
                {
                    figureList[0].Yfigure += 2;
                    figureList[1].Xfigure += 1; figureList[1].Yfigure += 1;
                    figureList[3].Xfigure -= 1; figureList[3].Yfigure -= 1;
                    currentPosition = FigurePosition.South;
                }
                if (nextPosition == FigurePosition.West)
                {
                    figureList[0].Xfigure -= 2;
                    figureList[1].Xfigure -= 1; figureList[1].Yfigure += 1;
                    figureList[3].Xfigure += 1; figureList[3].Yfigure -= 1;
                    currentPosition = FigurePosition.West;
                }
                if (nextPosition == FigurePosition.North)
                {
                    figureList[0].Yfigure -= 2;
                    figureList[1].Xfigure -= 1; figureList[1].Yfigure -= 1;
                    figureList[3].Xfigure += 1; figureList[3].Yfigure += 1;
                    currentPosition = FigurePosition.North;
                }
            }

            if (currentFigure == CurrentFigure.Stick)
            {
                CheckNextPosition(currentPosition);
                if (nextPosition == FigurePosition.East)
                {
                    figureList[0].Xfigure += 2; figureList[0].Yfigure -= 2;
                    figureList[1].Xfigure += 1; figureList[1].Yfigure -= 1;
                    figureList[3].Xfigure -= 1; figureList[3].Yfigure += 1;
                    currentPosition = FigurePosition.West;
                }
                if (nextPosition == FigurePosition.North)
                {
                    figureList[0].Xfigure -= 2; figureList[0].Yfigure += 2;
                    figureList[1].Xfigure -= 1; figureList[1].Yfigure += 1;
                    figureList[3].Xfigure += 1; figureList[3].Yfigure -= 1;
                    currentPosition = FigurePosition.North;
                }
            }

        }

        public void DeletingCompleteLines(List<int> coordYCompleteLine)
        {
            for (int i = 0; i < finishedList.Count; i++)
            {
                for (int j = 0; j < coordYCompleteLine.Count; j++)
                {
                    if (finishedList[i].Yfigure == coordYCompleteLine[j])
                    {
                        finishedList.Remove(finishedList[i]);
                        --i;
                    }
                }
            }
        }

        public void MoveLogic()
        {
            NextFigureGeneration();
            do
            {
                if (Console.KeyAvailable)
                {
                    key = Console.ReadKey(true);
                }
                
                if (key.Key == ConsoleKey.LeftArrow || key.Key == ConsoleKey.RightArrow || key.Key == ConsoleKey.UpArrow)
                {
                    hd.Control(key);
                    for (int i = 0; i < figureList.Count; i++)
                    {
                        drw.DrawFigure(figureList[i]);
                    }
                    System.Threading.Thread.Sleep(400);
                    foreach (var item in figureList)
                    {
                        drw.ClearFigure(item);
                    }
                }
               
                if (!Validation.IsOnDown(field, figureList) && !Validation.IsOnFinishedList(figureList, finishedList))
                {
                    foreach (var item in figureList)
                    {
                        item.MoveDown();
                    }
                }

                for (int i = 0; i < figureList.Count; i++)
                {
                    drw.DrawFigure(figureList[i]);
                }

                System.Threading.Thread.Sleep(200);

                foreach (var item in figureList)
                {
                    drw.ClearFigure(item);
                }

                key = default(ConsoleKeyInfo);

                if (Validation.IsOnDown(field, figureList) || Validation.IsOnFinishedList(figureList, finishedList))
                {
                    for (int i = 0; i < figureList.Count; i++)
                    {
                        finishedList.Add(figureList[i]);
                    }
                    figureList.Clear();
                    NextFigureGeneration();
                    currentPosition = FigurePosition.North;
                    if (Validation.IsLineComplete(finishedList, field))
                    {
                        coordYCompleteLine = Validation.CoordYCompleteLine(finishedList, field);
                        foreach (var element in finishedList)
                        {
                            drw.ClearFigure(element);
                        }
                        DeletingCompleteLines(coordYCompleteLine);

                        for (int j = 0; j < coordYCompleteLine.Count; j++)
                        {
                            foreach (var item in finishedList)
                            {
                                if (item.Yfigure < coordYCompleteLine[j])
                                {
                                    item.MoveDown();
                                }
                            }
                        }
                            
                        
                    }

                }


                foreach (var element in finishedList)
                {
                    drw.DrawFigure(element);
                }
            } while (true);
        }


    }
}
